"""
患者相关的 Pydantic 模型
"""
from pydantic import BaseModel, Field, validator
from typing import Optional
from datetime import datetime
from decimal import Decimal


# ========== 基础模型 ==========
class PatientBase(BaseModel):
    """患者基础字段"""
    name: str = Field(..., min_length=1, max_length=100, description="患者姓名")
    phone: Optional[str] = Field(None, max_length=20, description="手机号")
    id_card: Optional[str] = Field(None, max_length=25, description="身份证号")
    gender: Optional[str] = Field(None, description="性别")
    age: Optional[int] = Field(None, ge=0, le=150, description="年龄")
    height: Optional[Decimal] = Field(None, ge=0, description="身高(cm)")
    weight: Optional[Decimal] = Field(None, ge=0, description="体重(kg)")
    handedness: Optional[str] = Field(None, description="惯用手")
    
    # 疾病史
    diabetes: bool = Field(default=False, description="糖尿病")
    hypertension: bool = Field(default=False, description="高血压")
    hyperlipidemia: bool = Field(default=False, description="高血脂")
    stroke_history: bool = Field(default=False, description="卒中史")
    heart_disease: bool = Field(default=False, description="心脏病")
    atrial_fibrillation: bool = Field(default=False, description="房颤")
    sleep_apnea: bool = Field(default=False, description="睡眠呼吸暂停")
    
    # 吸烟史
    has_smoking_history: bool = Field(default=False, description="有吸烟史")
    smoking_amount: Optional[int] = Field(None, ge=0, description="吸烟量(支/天)")
    smoking_years: Optional[int] = Field(None, ge=0, description="吸烟年限")
    has_quit_smoking: Optional[bool] = Field(None, description="已戒烟")
    
    # 饮酒史
    has_drinking_history: bool = Field(default=False, description="有饮酒史")
    drinking_amount: Optional[int] = Field(None, ge=0, description="饮酒量(ml/天)")
    drinking_years: Optional[int] = Field(None, ge=0, description="饮酒年限")
    has_quit_drinking: Optional[bool] = Field(None, description="已戒酒")
    
    doctor_id: Optional[int] = Field(None, description="负责医生ID")
    avatar: Optional[str] = Field(None, description="头像URL")
    
    @validator('gender')
    def validate_gender(cls, v):
        # 兼容多种性别表示方式
        if v and v not in ['男', '女', '男性', '女性', 'male', 'female']:
            raise ValueError('性别只能是：男/女/男性/女性')
        return v
    
    @validator('handedness')
    def validate_handedness(cls, v):
        # 兼容多种惯用手表示方式
        if v and v not in ['左手', '右手', '左利手', '右利手', '左', '右']:
            raise ValueError('惯用手只能是：左手/右手/左利手/右利手')
        return v
    
    @validator('smoking_amount', 'smoking_years', 'drinking_amount', 'drinking_years', pre=True)
    def empty_string_to_none(cls, v):
        """将空字符串转换为 None"""
        if v == '' or v is None:
            return None
        return v
    
    @validator('height', 'weight', pre=True)
    def convert_decimal(cls, v):
        """处理空字符串和数字转换"""
        if v == '' or v is None:
            return None
        return v


# ========== 创建患者 ==========
class PatientCreate(PatientBase):
    """
    创建患者时的输入
    ⚠️ 与原 Flask 项目保持一致，以下字段必填：name, gender, phone, id_card
    """
    # 覆盖基类，将这些字段设为必填
    phone: str = Field(..., max_length=20, description="手机号（必填）")
    id_card: str = Field(..., max_length=25, description="身份证号（必填）")
    gender: str = Field(..., description="性别（必填）")
    
    class Config:
        json_schema_extra = {
            "example": {
                "name": "张三",
                "phone": "13800138001",
                "id_card": "110101199001011234",
                "gender": "男",
                "age": 65,
                "height": 170.5,
                "weight": 70.0,
                "handedness": "右手",
                "diabetes": True,
                "hypertension": True,
                "doctor_id": 1
            }
        }


# ========== 更新患者 ==========
class PatientUpdate(BaseModel):
    """更新患者信息（所有字段可选）"""
    name: Optional[str] = Field(None, min_length=1, max_length=100)
    phone: Optional[str] = Field(None, max_length=20)
    id_card: Optional[str] = Field(None, max_length=25)
    gender: Optional[str] = None
    age: Optional[int] = Field(None, ge=0, le=150)
    height: Optional[Decimal] = Field(None, ge=0)
    weight: Optional[Decimal] = Field(None, ge=0)
    handedness: Optional[str] = None
    
    diabetes: Optional[bool] = None
    hypertension: Optional[bool] = None
    hyperlipidemia: Optional[bool] = None
    stroke_history: Optional[bool] = None
    heart_disease: Optional[bool] = None
    atrial_fibrillation: Optional[bool] = None
    sleep_apnea: Optional[bool] = None
    
    has_smoking_history: Optional[bool] = None
    smoking_amount: Optional[int] = Field(None, ge=0)
    smoking_years: Optional[int] = Field(None, ge=0)
    has_quit_smoking: Optional[bool] = None
    
    has_drinking_history: Optional[bool] = None
    drinking_amount: Optional[int] = Field(None, ge=0)
    drinking_years: Optional[int] = Field(None, ge=0)
    has_quit_drinking: Optional[bool] = None
    
    doctor_id: Optional[int] = None
    avatar: Optional[str] = None
    
    @validator('smoking_amount', 'smoking_years', 'drinking_amount', 'drinking_years', pre=True)
    def empty_string_to_none(cls, v):
        """将空字符串转换为 None"""
        if v == '' or v is None:
            return None
        return v
    
    @validator('height', 'weight', pre=True)
    def convert_decimal(cls, v):
        """处理空字符串和数字转换"""
        if v == '' or v is None:
            return None
        return v


# ========== 患者响应 ==========
class PatientResponse(PatientBase):
    """API返回的患者数据"""
    id: int
    status: int
    created_at: datetime
    updated_at: datetime
    
    class Config:
        from_attributes = True
    
    def to_flask_format(self) -> dict:
        """
        转换为原 Flask 项目的响应格式
        ⚠️ 注意：原 Flask 项目使用下划线命名，不是驼峰命名！
        """
        return {
            "_id": str(self.id),
            "name": self.name,
            "phone": self.phone,
            "id_card": self.id_card,
            "gender": self.gender,
            "age": self.age,
            "height": float(self.height) if self.height else None,
            "weight": float(self.weight) if self.weight else None,
            "handedness": self.handedness,
            "diabetes": self.diabetes,
            "hypertension": self.hypertension,
            "hyperlipidemia": self.hyperlipidemia,
            "stroke_history": self.stroke_history,
            "heart_disease": self.heart_disease,
            "atrial_fibrillation": self.atrial_fibrillation,
            "sleep_apnea": self.sleep_apnea,
            "has_smoking_history": self.has_smoking_history,
            "smoking_amount": self.smoking_amount,
            "smoking_years": self.smoking_years,
            "has_quit_smoking": self.has_quit_smoking,
            "has_drinking_history": self.has_drinking_history,
            "drinking_amount": self.drinking_amount,
            "drinking_years": self.drinking_years,
            "has_quit_drinking": self.has_quit_drinking,
            "belong_doctor": str(self.doctor_id) if self.doctor_id else None,  # ⚠️ 原字段名
            "avatar": self.avatar,
            "status": self.status,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None
        }


# ========== 患者简要信息 ==========
class PatientBrief(BaseModel):
    """患者简要信息（用于列表展示）"""
    id: int
    name: str
    phone: Optional[str]
    gender: Optional[str]
    age: Optional[int]
    doctor_id: Optional[int]
    status: int
    created_at: datetime
    
    class Config:
        from_attributes = True


# ========== 患者微信登录 ==========
class PatientWxLogin(BaseModel):
    """患者微信登录"""
    id_card: str = Field(..., description="身份证号")
    phone: str = Field(..., description="手机号")
    
    class Config:
        json_schema_extra = {
            "example": {
                "id_card": "110101199001011234",
                "phone": "13800138001"
            }
        }


# ========== 患者登录响应（适配原 Flask 格式）==========
class PatientLoginResponse(BaseModel):
    """
    患者登录响应 - 适配原 Flask 项目格式
    原项目返回所有患者字段，_id 转换为字符串
    """
    
    @classmethod
    def from_patient(cls, patient) -> dict:
        """
        从 Patient 对象创建响应
        返回格式与原 Flask 项目一致（所有字段 + _id 字符串）
        """
        data = {
            "_id": str(patient.id),
            "name": patient.name,
            "phone": patient.phone,
            "id_card": patient.id_card,
            "gender": patient.gender,
            "age": patient.age,
            "height": float(patient.height) if patient.height else None,
            "weight": float(patient.weight) if patient.weight else None,
            "handedness": patient.handedness,
            "diabetes": patient.diabetes,
            "hypertension": patient.hypertension,
            "hyperlipidemia": patient.hyperlipidemia,
            "stroke_history": patient.stroke_history,
            "heart_disease": patient.heart_disease,
            "atrial_fibrillation": patient.atrial_fibrillation,
            "sleep_apnea": patient.sleep_apnea,
            "has_smoking_history": patient.has_smoking_history,
            "smoking_amount": patient.smoking_amount,
            "smoking_years": patient.smoking_years,
            "has_quit_smoking": patient.has_quit_smoking,
            "has_drinking_history": patient.has_drinking_history,
            "drinking_amount": patient.drinking_amount,
            "drinking_years": patient.drinking_years,
            "has_quit_drinking": patient.has_quit_drinking,
            "doctor_id": patient.doctor_id,
            "avatar": patient.avatar,
            "status": patient.status,
            "created_at": patient.created_at.isoformat() if patient.created_at else None,
            "updated_at": patient.updated_at.isoformat() if patient.updated_at else None
        }
        return data

